package com.example.demo.Service;

import cn.hutool.core.collection.CollectionUtil;
import com.example.demo.Entity.RegisterFunctionCmd;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.ssssssss.magicapi.model.Constants;
import org.ssssssss.magicapi.model.FunctionInfo;
import org.ssssssss.magicapi.model.Group;
import org.ssssssss.magicapi.model.Parameter;
import org.ssssssss.magicapi.provider.MagicAPIService;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MyFunctionService {
    @Autowired
    MagicAPIService magicAPIService;
    @Transactional
    public void registerFunction(RegisterFunctionCmd registerFunctionCmd) throws Exception {
        FunctionInfo functionInfo = getfunctionInfo(registerFunctionCmd);
        //TODO: savaFunction需要重写
        //savaFunction包含了设置id
        // 默认function的return设置为输入，如果输入在函数内改变，返回出的值将影响SQL参数改变

        magicAPIService.saveFunction(functionInfo);

    }
    private FunctionInfo getfunctionInfo(RegisterFunctionCmd registerFunctionCmd) throws Exception {
        FunctionInfo functionInfo = new FunctionInfo();
        functionInfo.setDescription(registerFunctionCmd.getDesc());
        functionInfo.setPath(registerFunctionCmd.getPath());
        functionInfo.setParameters(registerFunctionCmd.getParameters());
        // ReturnType写死为object，为了将更改的值传出来修改SQL参数
        // invoke函数传形参对象时，由于源码又做了一次形参对象的封装，导致无法直接传对象进去修改
        // 需要通过默认magic内的返回一个Object类型的Map，传出来再修改参数
        functionInfo.setReturnType("java.lang.Object");
        functionInfo.setName(registerFunctionCmd.getName());
        // 脚本默认返回所有传入的参数
        functionInfo.setScript(registerFunctionCmd.getScript());
        String groupId = getGroupId(registerFunctionCmd);
        functionInfo.setGroupId(groupId);
        log.info("test:"+registerFunctionCmd.getDesc());
        log.info("test:"+registerFunctionCmd.getPath());
        log.info("test:"+registerFunctionCmd.getParameters());
        log.info("test:"+registerFunctionCmd.getReturnType());
        log.info("test:"+registerFunctionCmd.getName());
        log.info("test:"+registerFunctionCmd.getScript());
        log.info("test:"+groupId);
        return functionInfo;
    }
//    private String getScript(RegisterFunctionCmd registerFunctionCmd) throws Exception {
//        List<Parameter> parameters = registerFunctionCmd.getParameters();
//        // 防止变量名重复的错误
//        if (StrUtil.contains(registerFunctionCmd.getScript(),"magicFunctionReturnMap")){
//            throw new Exception("不要使用关键词magicFunctionReturnMap作为变量名");
//        }
//        // 如何取舍返回值交给用户写让用户增加学习成本，还是自己写死
//        String newScript = "";
//        return registerFunctionCmd.getScript() + newScript;
//    }
    private String getGroupId(RegisterFunctionCmd registerFunctionCmd){
        // 如果registerFunctionCmd没获取到Group信息
        if(StringUtils.isBlank(registerFunctionCmd.getFuncGroup())) {
            // 去工作空间中找所有的GROUP_TYPE_FUNCTION标签的Group
            // 找到名称与当前工作空间id相同的所有的Group集合
            List<Group> groupsOfSpecName = magicAPIService.groupList(Constants.GROUP_TYPE_FUNCTION).stream().filter(
                    group -> {
                        return registerFunctionCmd.getWorkspaceId().toString().equals(group.getName());
                    }
            ).collect(Collectors.toList());
            // 若为空，就新建一个与工作空间ID为名称和路径的Group并返回
            if (CollectionUtil.isEmpty(groupsOfSpecName)) {
                Group group = new Group();
                group.setName(registerFunctionCmd.getWorkspaceId().toString());
                group.setType(Constants.GROUP_TYPE_FUNCTION);
                group.setPath(registerFunctionCmd.getWorkspaceId().toString());
                return magicAPIService.createGroup(group);
            } else {
                // 若不为空，返回其中Group的id值最小的那个返回
                groupsOfSpecName.sort((a, b) -> {
                    return a.getId().compareTo(b.getId());
                });
                return groupsOfSpecName.get(0).getId();
            }
        }else{
            // 如果GuidedRegisterApiCmd包含Group路径
            // 查找该Group路径是否存在
            List<Group> groupsOfSpecName = magicAPIService.groupList(Constants.GROUP_TYPE_FUNCTION).stream().filter(
                    group -> {
                        return registerFunctionCmd.getWorkspaceId().equals(group.getName());
                    }
            ).collect(Collectors.toList());
            // 若为空，用这个Group路径新建一个Group
            if (CollectionUtil.isEmpty(groupsOfSpecName)) {
                Group group = new Group();
                group.setName(registerFunctionCmd.getFuncGroup());
                group.setType(Constants.GROUP_TYPE_FUNCTION);
                group.setPath(registerFunctionCmd.getFuncGroup());
                return magicAPIService.createGroup(group);
            } else {
                // 若不为空，返回其中Group的id值最小的那个
                // 由于groupList返回的是所有group，可能存在某个其他集合的子group的名称
                // 和当前传入的group相同
                // 使得返回的结果大于1
                //
                groupsOfSpecName.sort((a, b) -> {
                    return a.getId().compareTo(b.getId());
                });
                return groupsOfSpecName.get(0).getId();
            }
        }
    }


}
